package com.fingard.dsp.bank.directbank.cmbunion01;


import com.fingard.common.utils.json.JSONUtils;
import com.fingard.crypto.DigestHelper;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.directbank.cmbunion01.util.BoingPay;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.util.SortHelper;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CMBUnion01Base extends DirectBase {
	protected String getCharset() {
		return getBankConfig().getCharset("UTF-8");
	}
	
	public HashMap<String, String> getOpenid(String p_appId, String p_appSecret, String p_code) {
		HashMap<String, String> retHash = new HashMap<String, String>();

		String respCode = "";
		String respInfo = "";

		String tmpUrl = bankFront.getUrl("access_token");
		if (StringHelper.isNullOrEmpty(tmpUrl)) {
			respCode = "-1";
			respInfo = "未设置“通过code换取网页授权access_token”的地址,请检查BankFront.xml相关配置!";
		} else {
			tmpUrl = tmpUrl + "?appid=" + p_appId + "&secret=" + p_appSecret + "&code=" + p_code
					+ "&grant_type=authorization_code";
			WriteBankLogStep2(tmpUrl);

			WebRequest tmpWebRequest = new WebRequest(tmpUrl);
			String[] tmpRet = tmpWebRequest.upload(null, getCharset());
			if (tmpRet[0].length() == 0) {
				WriteBankLogStep3(tmpRet[1]);

				if (tmpRet[1].startsWith("{")) {
					retHash = JSONUtils.json2Map(tmpRet[1]);
					respCode = "0";
				} else {
					respCode = "-1";
					respInfo = tmpRet[1];
				}
			} else {
				respCode = "-1";
				respInfo = tmpRet[1];
				WriteBankLogLn(tmpRet[0] + "\r\n" + tmpRet[1]);
			}
		}

		retHash.put("RespCode", respCode);
		retHash.put("RespInfo", respInfo);

		return retHash;
	}
	/**
     * 把单位由元换算成单位为分
     * @param amount 金额（元）
     */
    public String changeCurToFen(String amount){
        BigDecimal bigDecimal = new BigDecimal(amount);
        return bigDecimal.multiply(new BigDecimal(100)).setScale(0).toString();
    }
    /**
     * 初始化BoingPay
     * @throws Exception
     */
    public void setConfig(String appId,String url,String RSAcert,String RSApfx,String DSAcert,String DSApfx,String password) throws Exception {
        BoingPay.setAppId(appId);//系统接入方APPID，可以是渠道商身份或者商户身份
        BoingPay.setServerUrl(url);//对接版本
        BoingPay.setApiVersion("2.0");//DSA公钥，DSA私钥
        BoingPay.setRSAKey(RSAcert, RSApfx, password);//DSA公钥，DSA私钥
        BoingPay.setDSAKey(DSAcert, DSApfx, password);//RSA公钥，RSA私钥
    }
    public void setConfig(String DSAcert,String DSApfx,String password) throws Exception {
        BoingPay.setDSAKey(DSAcert, DSApfx, password);
    }
    
    /**
	 * 返回HTTP字符串转MAP
	 * 
	 * @param plainStr
	 * @return
	 */
	public static Map<String,String> convertToMap(String srcStr) {
		Map<String,String> params = new HashMap<String,String>();
		
		String[] nodes = srcStr.split("&");
		for (String node : nodes) {
			int index = node.indexOf("=");
			
			String key = node.substring(0, index);
			String value = node.substring(index+1);
			
			params.put(key, value);
		}
		
		return params;
	}
	public String request(Map<String, String> args,String serverUrl,String tempfile) throws Exception {
        String result = "";
        HttpPost post = new HttpPost(serverUrl);
        post.setHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8");
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        for (Map.Entry<String, String> entry : args.entrySet()) {
            nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
        }
        HttpEntity entity = new UrlEncodedFormEntity(nvps, "utf-8");
        post.setEntity(entity);
        RequestConfig.Builder customReqConf = RequestConfig.custom();
        customReqConf.setConnectTimeout(10000);
        customReqConf.setSocketTimeout(10000);
        //使用代理
        boolean enableProxy = getBankConfig().getValueAsBool("enableProxy");
        if(enableProxy){
            String proxyIP = getBankConfig().getValueAsString("proxyIP");
            int proxyPort = Integer.parseInt(getBankConfig().getValueAsString("proxyPort"));
            HttpHost proxy = new HttpHost(proxyIP,proxyPort,"http");
            customReqConf.setProxy(proxy);
        }
        post.setConfig(customReqConf.build());
        HttpClient httpClient = createSSLInsecureClient();
        HttpResponse httpResponse = httpClient.execute(post);
        int statusCode = httpResponse.getStatusLine().getStatusCode();
        if (statusCode == 200) {
            String contentType = null;
            if (httpResponse.getEntity().getContentType() != null) {
                contentType = httpResponse.getEntity().getContentType().toString();
            }
            System.out.println("contentType:" + contentType);
            InputStream inputStream = httpResponse.getEntity().getContent();
            int len;
            if (!StringUtils.isBlank(contentType) && contentType.contains("text/html")) {
                try {
                    StringBuffer sb = new StringBuffer();
                    if (inputStream != null) {
                        sb.setLength(0);
                        InputStreamReader reader = new InputStreamReader(inputStream, "utf-8");
                        char[] cbuf = new char[1024];
                        while( (len = reader.read(cbuf, 0, cbuf.length)) != -1 ) {
                            sb.append(new String(cbuf, 0, len));
                        }
                        reader.close();
                        System.out.println(sb.toString());
                        return sb.toString();
                    }
                } finally {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                }

            } else {
            FileOutputStream os = null;
            try {
                try {
                    File file = new File(tempfile);//文件存储目录
                    os = new FileOutputStream(file);
                    byte[] b = new byte[2048];
                    int length;
                    while ((length = inputStream.read(b)) > 0) {
                        os.write(b, 0, length);
                    }
                } catch (Exception exception) {
                    exception.printStackTrace();
                }
            } finally {
                if (os != null) {
                    os.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            }
            }
        } else {
            throw new Exception("Unexpected server response: " + statusCode);
        }
        return null;
    }
	private static CloseableHttpClient createSSLInsecureClient() throws GeneralSecurityException {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }
        }).build();
        SSLConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext, new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }
        });
        return HttpClients.custom().setSSLSocketFactory(sslSF).build();
    }
	public String signMessage(String[] p_params, String p_saltKey) throws Exception{
		String[] sortedValues = SortHelper.BubbleSort(p_params);
		StringBuilder sbValues = new StringBuilder();
        for (int i = 0; i < sortedValues.length; i++){
            if (i > 0){
            	sbValues.append("&");
            }
            sbValues.append(sortedValues[i]);
        }
        sbValues.append("&key="+p_saltKey);
        WriteBankLogLn2("签约原始数据:\r\n" + sbValues.toString());
        byte[] tmpDataBytes = sbValues.toString().getBytes(getCharset());
		return DigestHelper.cryptoMD5RetHexStr(tmpDataBytes).toUpperCase();
	}
	
}
